﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OpenPasteSpider.noticemodels;
using OpenPasteSpider.usermodel;
using Volo.Abp.DependencyInjection;

namespace OpenPasteSpider
{
    /// <summary>
    /// 消息推送处理
    /// </summary>
    public class NoticeTaskHanlder : ISingletonDependency
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly IHttpClientFactory _client;
        private readonly ICacheHelper _cache;
        private readonly ILogger<NoticeTaskHanlder> _logger;
        /// <summary>
        /// 
        /// </summary>
        public NoticeTaskHanlder(IServiceProvider serviceProvider, IHttpClientFactory client, ICacheHelper cache, ILogger<NoticeTaskHanlder> logger)
        {
            _serviceProvider = serviceProvider;
            _client = client;
            _cache = cache;
            _logger = logger;
        }

        /// <summary>
        /// 推送消息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<bool> DoSendNoticeAsync(SlaveNoticeItem info)
        {
            using var _scope = _serviceProvider.CreateScope();
            using var _dbContext = _scope.ServiceProvider.GetRequiredService<IOpenPasteSpiderDbContext>();
            var revicelist = _cache.GetObject<List<RevicerInfoDto>>($"{PublicString.CacheNoticeReviceHead}{info.Code}");
            if (revicelist == null || revicelist == default)
            {
                var list = await _dbContext.RevicerInfo.Where(x => x.IsEnable && (x.Codes == "|all|" || x.Codes.Contains(info.Code))).AsNoTracking().ToListAsync();
                if (list != null && list.Count > 0)
                {
                    revicelist = list.Select(x => new RevicerInfoDto
                    {
                        Id = x.Id,
                        Codes = x.Codes,
                        IsEnable = x.IsEnable,
                        Name = x.Name,
                        Url = x.Url
                    }).ToList();
                }
                else
                {
                    revicelist = new List<RevicerInfoDto>();
                }

                _cache.SetObject($"{PublicString.CacheNoticeReviceHead}{info.Code}", revicelist, 300);
            }

            var listlog = new List<NoticeLog>();

            if (revicelist != null)
            {
                foreach (var item in revicelist)
                {
                    listlog.Add(await PostNoticeToUrl(item.Url, item.Id, info));
                }
            }
            else
            {
                _logger.LogWarning($"not found code:{info.Code} revicer!");
            }

            if (listlog.Count > 0)
            {
                _dbContext.AddRange(listlog);
                await _dbContext.SaveChangesAsync();
                _dbContext.Dispose();
                _scope.Dispose();
            }

            return true;
        }

        /// <summary>
        /// 推送消息 不等待
        /// </summary>
        /// <param name="url"></param>
        /// <param name="uid"></param>
        /// <param name="message"></param>
        private async Task<NoticeLog> PostNoticeToUrl(string url, int uid, SlaveNoticeItem message)
        {
            NoticeLog log = new NoticeLog();
            try
            {
                log.CreateDate = DateTime.Now;
                log.Body = message.Body;
                log.Code = message.Code;
                log.ObjId = message.ObjId;
                log.RevicerId = uid;
                log.Success = false;


                log.Success = await SendNoticeToUrl(url, message);
            }
            catch (Exception exl)
            {
                _logger.LogException(exl);
            }
            return log;
        }


        /// <summary>
        /// 推送给用户 等待
        /// </summary>
        /// <param name="url"></param>
        /// <param name="message"></param>
        private async Task<bool> SendNoticeToUrl(string url, SlaveNoticeItem message)
        {

            //兼容钉钉和飞书的推送模式
            var json = new { msgtype = "text", msg_type = "text", content = new { text = $"{message.Body}" }, text = new { content = $"{message.Body}" } };

            var postdata = (Newtonsoft.Json.JsonConvert.SerializeObject(json));

            using (HttpContent httpcontent = new StringContent(postdata))
            {
                httpcontent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
                var client = _client.CreateClient();
                client.Timeout = TimeSpan.FromSeconds(4);
                var response = await client.PostAsync(url, httpcontent);
                if (response.IsSuccessStatusCode)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }


    }
}
